package com.jungle.task.executor;

import com.jungle.task.Task;
import com.jungle.task.TaskPool;
import com.jungle.task.parameter.CompensateTaskParameter;
import com.jungle.task.result.CompensateTaskResult;

import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author 李岩 at 2021/10/23.
 */
public class DefaultAsyncCompensateTaskExecutor implements CompensateTaskExecutor,Runnable, ThreadFactory {
    private final TaskPool<CompensateTaskParameter,CompensateTaskResult> taskPool;

    public DefaultAsyncCompensateTaskExecutor(){
        this.taskPool = new TaskPool<>();
        final ExecutorService executorService = new ThreadPoolExecutor(1,1,10, TimeUnit.MINUTES,null,this);
        executorService.submit(this);
    }

    /**
     * 执行任务
     *
     * @param task 任务
     * @return res
     */
    @Override
    public CompensateTaskResult execute(final Task<CompensateTaskParameter, CompensateTaskResult> task) {
        final CompensateTaskParameter parameter = task.getParameter();
        if (Objects.nonNull(parameter.getFailedExecutors()) && !parameter.getFailedExecutors().isEmpty()){
            publishTaskToQueue(task);
        }
        return new CompensateTaskResult(true);
    }


    @Override
    public void run() {
        while (true){
            try {
                final Task<CompensateTaskParameter,CompensateTaskResult> task = this.takeTask();
                final CompensateTaskParameter parameter = task.getParameter();
                if (Objects.nonNull(parameter.getFailedExecutors()) && !parameter.getFailedExecutors().isEmpty()){
                    parameter.getContext().publishTask(parameter.getSaveTask(), parameter.getFailedExecutors());
                }
            }catch (final Exception e){

            }
        }
    }

    public void publishTaskToQueue(final Task<CompensateTaskParameter,CompensateTaskResult> task){
        this.taskPool.publishTask(task);
    }

    public Task<CompensateTaskParameter,CompensateTaskResult> takeTask(){
        return this.taskPool.takeTask();
    }


    @Override
    public Thread newThread(final Runnable r) {
        final Thread thread = new Thread(r,"fsc-compensate-thread");
        thread.setDaemon(true);
        return thread;
    }
}
